package com.csap.framework.integration.client.boot.autoconfigure;

import com.aliyun.openservices.ons.api.MessageListener;
import com.csap.framework.integration.consumer.EnableRocketmqBean;
import com.csap.framework.util.StringUtil;
import lombok.SneakyThrows;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * @author yangchengfu
 * @description 自定义 注册
 * @dataTime 2020年-09月-22日 13:30:00
 **/
@Component
public class RocketmqListenerImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar, BeanFactoryAware {
    private Map<String, Object> annotationAttributes;
    private BeanFactory beanFactory;

    @SneakyThrows
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        this.annotationAttributes = importingClassMetadata.getAnnotationAttributes(EnableRocketmqListener.class.getName());
        if (this.annotationAttributes != null) {
            Class<?> cClass = Class.forName(importingClassMetadata.getClassName());
            String topic = (String) annotationAttributes.get("topic");
            String tags = (String) annotationAttributes.get("tag");
            String key = (String) annotationAttributes.get("key");
            Environment environment = beanFactory.getBean(Environment.class);
            registerBean(registry, StringUtil.lowerFirst(EnableRocketmqBean.class.getSimpleName()), EnableRocketmqBean.class).add(EnableRocketmqBean.RocketmqBean.builder()
                    .aClass((Class<? extends MessageListener>) cClass)
                    .topic(environment.resolveRequiredPlaceholders(topic))
                    .tag(environment.resolveRequiredPlaceholders(tags))
                    .key(environment.resolveRequiredPlaceholders(key))
                    .build());
        }
    }


    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    /**
     * 检查并注册Bean
     *
     * @param registry
     * @param name
     * @param beanClass
     */
    private <T> T registerBean(BeanDefinitionRegistry registry, String name, Class<T> beanClass) {
        // 检查指定类型的Bean name数组是否存在，如果不存在则创建Bean并注入到容器中
        if (!this.beanFactory.containsBean(name)) {
            RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass);
            registry.registerBeanDefinition(name, beanDefinition);
        }
        return this.beanFactory.getBean(beanClass);
    }
}
